﻿// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.

namespace Microsoft.Samples.Commerce.Order.CommerceEntities
{
    using Microsoft.Commerce.Contracts;
    
    /// <summary>
    /// Represents a user's saved item list. 
    /// </summary>
    public class ShopperList : ICommerceEntity
    {
        /// <summary>
        /// defines the model name for this commerce entity
        /// </summary>
        public const string ModelNameDefinition = "ShopperList";

        /// <summary>
        /// The commerce entity.
        /// </summary>
        private CommerceEntity commerceEntity;

        /// <summary>
        /// Initializes a new instance of the <see cref="ShopperList"/> class.
        /// </summary>
        public ShopperList()
        {
            this.commerceEntity = new CommerceEntity(ShopperList.ModelNameDefinition);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ShopperList"/> class.
        /// </summary>
        /// <param name="commerceEntity">The commerce entity.</param>
        public ShopperList(CommerceEntity commerceEntity)
        {
            this.commerceEntity = commerceEntity;
        }

        #region ICommerceEntity Members

        /// <summary>
        /// Gets or sets the id.
        /// </summary>
        /// <value>The id of the entity.</value>
        public string Id
        {
            get { return this.commerceEntity.Id; }
            set { this.commerceEntity.Id = value; }
        }

        /// <summary>
        /// Gets or sets the type name of this object instance
        /// <remarks>Required so that the Builders can convert to the Multi-channel Commerce Foundation CommerceEntity base type</remarks>
        /// </summary>
        /// <value></value>
        public string ModelName
        {
            get { return this.commerceEntity.ModelName; }
            set { this.commerceEntity.ModelName = value; }
        }

        /// <summary>
        /// Gets or sets this objects collection of Properties and their corresponding values
        /// </summary>
        /// <value></value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommercePropertyCollection Properties
        {
            get { return this.commerceEntity.Properties; }
            set { this.commerceEntity.Properties = value; }
        }

        #endregion

        /// <summary>
        /// Gets or sets the name of the basket.
        /// </summary>
        /// <value>The Shopping List name.</value>
        public string Name
        {
            get { return this.commerceEntity.GetPropertyValue(PropertyName.Name) as string; }
            set { this.commerceEntity.SetPropertyValue(PropertyName.Name, value); }
        }

        /// <summary>
        /// Gets or sets the user identifier of the shopper that the ShopperList belongs to.
        /// </summary>
        /// <value>The User id.</value>
        public string UserId
        {
            get { return this.commerceEntity.GetPropertyValue(PropertyName.UserId) as string; }
            set { this.commerceEntity.SetPropertyValue(PropertyName.UserId, value); }
        }
     
        /// <summary>
        /// Gets or sets the line item collection associated with the current basket.
        /// </summary>
        /// <value>The line items.</value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList LineItems
        {
            get { return this.commerceEntity.GetPropertyValue(RelationshipName.LineItems) as CommerceRelationshipList; }
            set { this.commerceEntity.SetPropertyValue(RelationshipName.LineItems, value); }
        }
      
        #region Implicit operators

        /// <summary>
        /// Implicit cast to ShopperList
        /// </summary>
        /// <param name="commerceEntity">The commerce entity.</param>
        /// <returns></returns>
        public static implicit operator ShopperList(CommerceEntity commerceEntity)
        {
            System.Diagnostics.Debug.Assert(ShopperList.ModelNameDefinition.Equals(commerceEntity.ModelName), "Unexpected model name");
            return new ShopperList(commerceEntity);
        }

        #endregion

        /// <summary>
        /// Required so that the Builders can convert to the Multi-channel Commerce Foundation CommerceEntity base type using <see cref="ModelName"/>
        /// </summary>
        /// <returns>This instances base type</returns>
        public CommerceEntity ToCommerceEntity()
        {
            return this.commerceEntity;
        }

        /// <summary>
        /// RelatedOperations of the ShoppingOperation CommerceEntity.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Justification = "Required because of API specification (i.e. DataContract design)")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Needed for external access"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Justification = "Cannot make it private as it cannot be derived from")]
        public class RelationshipName
        {
            /// <summary>
            /// Lineitems collection property name.
            /// </summary>
            public const string LineItems = "LineItems";
        }

        /// <summary>
        /// Properties of the ShopperList CommerceEntity.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Needed for external access"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Justification = "Cannot make it private as it cannot be derived from")]
        public class PropertyName : CommerceEntity.PropertyName
        {
            /// <summary>
            /// ShopperList Name property name.
            /// </summary>
            public const string Name = "Name";

            /// <summary>
            /// The owner of the Shopping List.
            /// </summary>
            public const string UserId = "UserId";                    
        }
    }  
}
